package com.tanhua.server.server;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.domian.Question;
import com.tanhua.model.domian.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.*;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.utils.Constants;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Value("${tanhua.default.recommend.users}")
    private String recommendUserList;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private MessageService messageService;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @DubboReference
    private FriendApi friendApi;


    //查询今日佳人数据
    public TodayBest todayBest() {
        //1 获取用户id
        Long userId = UserHolder.getUserId();
        //2 调用API查询
        RecommendUser recommendUser = recommendUserApi.queryWithMaxScore(userId);
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(1l);
            recommendUser.setScore(99d);
        }
        //3 将RecommendUser转化为TodayBest对象
        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        //4 返回
        return vo;
    }

    public PageResult recommendation(RecommendUserDto dto) {
        //获取用户ID   先在mongDB里面查询到推荐的好友， 后在mysql里面查询到好友的详细信息
        Long userId = UserHolder.getUserId();
        //查询mongdb里推荐好友
        PageResult pr = recommendUserApi.queryRecommendUserList(dto.getPage(), dto.getPagesize(), userId);
        //获取分页中的RecommendUserD的数据
        List<RecommendUser> items = (List<RecommendUser>) pr.getItems();
        //判断是否为空
        if (items == null || items.size() <= 0) {
            return pr;
        }
        //取出集合里面的推荐好友的ID
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
        //根据集合ID去msql拿ID的详细信息
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(dto.getGender());
        userInfo.setAge(dto.getAge());
        userInfo.setEducation(dto.getEducation());
        //构建查询条件查询所有ID的账户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
        //循环推荐列表，构建VO对象
        ArrayList<TodayBest> todayBests = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo userInfo1 = map.get(item.getUserId());
            if (userInfo1 != null) {
                TodayBest init = TodayBest.init(userInfo1, item);
                todayBests.add(init);
            }
        }
        pr.setItems(todayBests);
        return pr;
    }

    public TodayBest findPersonalInfo(Long id) {
        //查到本账户ID
        Long userId = UserHolder.getUserId();
        //查询佳人详细信息
        UserInfo userInfo = userInfoApi.findById(id);

        //查看本账户与佳人的缘分值
        RecommendUser recommendUser = recommendUserApi.queryScore(id, userId);

        //构建一个访问记录，如果无则保存，有则更新
        Visitors visitors = new Visitors();
        visitors.setUserId(id);
        visitors.setVisitorUserId(UserHolder.getUserId());
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);

        return TodayBest.init(userInfo, recommendUser);
    }

    public String queryQuestionById(Long id) {
        Question question = questionApi.findByUserId(id);
        return question == null ? "You like baby ？" : question.getTxt();
    }

    public void replyQuestions(Long userId, String reply) {
        //或扽本账户的id
        Long currentUserId = UserHolder.getUserId();
        //获得本账户ID的详细信息
        UserInfo userInfo = userInfoApi.findById(currentUserId);
        Map map = new HashMap();
        map.put("userId", currentUserId);
        map.put("huanXinId", Constants.HX_USER_PREFIX + userId);
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", queryQuestionById(userId));
        map.put("reply", reply);
        //转json发送
        String message = JSON.toJSONString(map);
        Boolean aBoolean = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }

    }

    public List<TodayBest> queryCradsList() {
        Long userId1 = UserHolder.getUserId();
        //调用recommentuserApi查询缘分值，要排除已经喜欢 和不喜欢的列表
        List<RecommendUser> userList = recommendUserApi.queryCardsList(userId1, 10);
        //判断里面是否有数据，不过没有就构造数据、
        if (CollUtil.isEmpty(userList)) {
            userList = new ArrayList<>();
            String[] userIds = recommendUserList.split(",");
            for (String userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getUserId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                userList.add(recommendUser);
            }
        }
        //构建VO
        List<Long> userId = CollUtil.getFieldValues(userList, "userId", Long.class);
        Map<Long, UserInfo> userInfomap = userInfoApi.findByIds(userId, null);
        ArrayList<TodayBest> todayBests = new ArrayList<>();
        for (RecommendUser recommendUser : userList) {
            UserInfo userInfo = userInfomap.get(recommendUser.getUserId());
            if (userInfo != null) {
                TodayBest init = TodayBest.init(userInfo, recommendUser);
                todayBests.add(init);
            }
        }
        return todayBests;
    }

    public void likeUser(Long likeuserId) {
        Long userId = UserHolder.getUserId();
        //调用Api用mongDB保存喜欢数据到userlike表
        boolean save = userLikeApi.likeuser(userId, likeuserId, true);
        if (!save) {
            //没有保存成功的话直接返回
            throw new BusinessException(ErrorResult.error());
        }
        //将数据存入redis，并且删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + userId, likeuserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + userId, likeuserId.toString());
        //判断是否双向喜欢，如果喜欢就添加好友
        if (islike(likeuserId, userId)) {
            messageService.addFriend(likeuserId);
        }
    }

    public boolean islike(Long userId, Long likeuserId) {
        String key = Constants.USER_LIKE_KEY + userId;
        return redisTemplate.opsForSet().isMember(key, likeuserId.toString());
    }

    public void dislikeUser(Long likeUserId) {
        Long userId = UserHolder.getUserId();
        //调用Api查询 是否已经点了喜欢，如果点了就更新成不喜欢，如果没点就新增不喜欢数据
        boolean result = userLikeApi.likeuser(userId, likeUserId, false);
        if (!result) {
            throw new BusinessException(ErrorResult.error());
        }
        //增加redis缓存,删除喜欢，添加不喜欢
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + userId, likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + userId, likeUserId.toString());

    }

    public List<NearUserVo> queryNearUser(String gender, String distance) {
        Long userId = UserHolder.getUserId();
        //根据userlocation查询附近的人
        List<Long> userlist = userLocationApi.queryNearUser(userId, Double.valueOf(distance));
        if (CollUtil.isEmpty(userlist)) {
            return new ArrayList<>();
        }
        //根据ID和性别找到用户信息
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(gender);
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userlist, userInfo);
        //利用userinfo封装数据给NearUservo 返回给前端
        ArrayList<NearUserVo> nearUserVos = new ArrayList<NearUserVo>();
        for (Long aLong : userlist) {
            //排除自己的账号
            if (userId == aLong) {
                continue;
            }
            UserInfo userInfo1 = userInfoMap.get(aLong);
            if (userInfo1 != null) {
                NearUserVo init = NearUserVo.init(userInfo1);
                nearUserVos.add(init);
            }
        }
        return nearUserVos;
    }

    public CountVo likeLoveCounts() {
        Long userId = UserHolder.getUserId();
        CountVo countVo = new CountVo();
        //mongDB里面查询我喜欢的数量
        List<UserLike> loveCounts = userLikeApi.loveCount(userId);
        Integer loveCountsSize = 0;
        if (loveCounts != null) {
            loveCountsSize = loveCounts.size();
        }
        countVo.setLoveCount(loveCountsSize);
        //mongDB里面查询喜欢我的的数量
        List<UserLike> fanCounts = userLikeApi.fanCount(userId);
        Integer fanCountsSize = 0;
        if (loveCounts != null) {
            fanCountsSize = fanCounts.size();
        }
        countVo.setFanCount(fanCountsSize);
        //mongDB里面查询互相喜欢的数量封装进vo
        //List <UserLike> eachLoveCounts =  userLikeApi.eachLoveCount(userId);
        //将fanCounts构建成为map，用里面的userid作为键
        Integer eachLoveCounts = 0;
        Map<Long, UserLike> fanCountsMap = CollUtil.fieldValueMap(fanCounts, "userId");
        for (UserLike loveCount : loveCounts) {
            UserLike userLike = fanCountsMap.get(loveCount.getLikeUserId());
            if (userLike != null) {
                eachLoveCounts++;
            }
        }
        countVo.setEachLoveCount(eachLoveCounts);
        return countVo;
    }

    public void cancelLikes(Long likeUserId) {
        Long userId = UserHolder.getUserId();
        //删除userlike表里面喜欢的likeUserId
        userLikeApi.cancelLikes(userId, likeUserId);
        //查询是否是好友，如果是就删除
        boolean result = friendApi.queryFriend(userId, likeUserId);
        //如果存在好友关系则删除表里面的数据
        if (result) {
            friendApi.removeFriend(userId, likeUserId);
            huanXinTemplate.deleteContact(Constants.HX_USER_PREFIX+userId,Constants.HX_USER_PREFIX+likeUserId);
        }
    }

    public void fansLike(Long likeuserId) {
        Long userId = UserHolder.getUserId();
        //调用Api用mongDB保存喜欢数据到userlike表
        boolean save = userLikeApi.likeuser(userId, likeuserId, true);
        if (!save) {
            //没有保存成功的话直接返回
            throw new BusinessException(ErrorResult.error());
        }
        //将数据存入redis，并且删除不喜欢的数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + userId, likeuserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + userId, likeuserId.toString());
        //判断是否双向喜欢，如果喜欢就添加好友
        if (islike(likeuserId, userId)) {
            messageService.addFriend(likeuserId);
        }
    }
}